package com.mlethe.library.calendarview;

import android.content.Context;
import android.graphics.Canvas;
import android.view.View;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;

/**
 * 月视图周选择控件,可自由继承实现
 *
 * @Author Mlethe
 * @Date 2023/1/31
 */
public abstract class WeekMonthView extends BaseMonthView {

    public WeekMonthView(Context context) {
        super(context);
    }

    /**
     * 开始绘制
     *
     * @param canvas   canvas
     * @param calendar 对应日历
     * @param row      行
     * @param column   列
     * @param position 位置
     */
    protected void draw(@NonNull Canvas canvas, @NonNull Calendar calendar, int row, int column, int position) {
        int x = column * mItemWidth + mDelegate.getCalendarPaddingLeft();
        int y = row * mItemHeight;
        onLoopStart(x, y);
        boolean isSelected = mCurrentItem >= 0 && mCurrentItem + 6 < mItems.size() && position >= mCurrentItem && position < mCurrentItem + 7;
        int weekPosition = isSelected ? position - mCurrentItem : -1;
        boolean hasScheme = calendar.hasScheme();

        if (hasScheme) {
            //标记的日子
            boolean isDrawSelected = false;//是否继续绘制选中的onDrawScheme
            if (isSelected) {
                isDrawSelected = onDrawSelected(canvas, calendar, x, y, true, weekPosition);
            }
            if (isDrawSelected || !isSelected) {
                //将画笔设置为标记颜色
                mSchemePaint.setColor(calendar.getSchemeColor() != 0 ? calendar.getSchemeColor() : mDelegate.getSchemeThemeColor());
                onDrawScheme(canvas, calendar, x, y);
            }
        } else {
            if (isSelected) {
                onDrawSelected(canvas, calendar, x, y, false, weekPosition);
            }
        }
        onDrawText(canvas, calendar, x, y, hasScheme, isSelected, weekPosition);
    }

    @Override
    public void onClick(View view) {
        if (!isClick) return;
        int position = getIndex();
        if (position == -1) return;
        Calendar calendar = mItems.get(position);
        boolean isCurrentMonth = calendar.isCurrentMonth();
        if (mDelegate.getMonthViewShowMode() == CalendarViewDelegate.MODE_ONLY_CURRENT_MONTH && !isCurrentMonth) {
            return;
        }
        mDelegate.setSelectedCalendar(calendar);
        int startPosition = mCurrentItem;
        int startPos = position - CalendarUtil.getWeekFirstDayDiff(calendar, mDelegate.getWeekStart());
        if (startPos >= 0 && startPos + 6 < mItems.size()) {
            startPosition = startPos;
        }
        if (isCurrentMonth || !isInRange(calendar)) {
            mCurrentItem = startPosition;
            invalidate();
        } else {
            mCurrentItem = -1;
            if (mOnCalendarClickListener != null) {
                mOnCalendarClickListener.onClick(calendar, position);
            }
        }
        if (startPosition >= 0 && mDelegate.mWeekSelectListener != null) {
            List<Calendar> list = new ArrayList<>();
            for (int i = 0; i < 7; i++) {
                list.add(mItems.get(startPosition + i));
            }
            mDelegate.mWeekSelectListener.onWeekSelect(list, isClick);
        }
    }

    @Override
    public boolean onLongClick(View v) {
        if (mDelegate.mWeekLongClickListener == null) return false;
        if (!isClick) return false;
        int position = getIndex();
        if (position == -1) return false;
        Calendar calendar = mItems.get(position);
        boolean isCurrentMonth = calendar.isCurrentMonth();
        if (mDelegate.getMonthViewShowMode() == CalendarViewDelegate.MODE_ONLY_CURRENT_MONTH && !isCurrentMonth) {
            return false;
        }
        mDelegate.setSelectedCalendar(calendar);
        int startPosition = mCurrentItem;
        int startPos = position - CalendarUtil.getWeekFirstDayDiff(calendar, mDelegate.getWeekStart());
        if (startPos >= 0 && startPos + 6 < mItems.size()) {
            startPosition = startPos;
        }
        if (isCurrentMonth || !isInRange(calendar)) {
            mCurrentItem = startPosition;
            invalidate();
        } else {
            mCurrentItem = -1;
            if (mOnCalendarClickListener != null) {
                mOnCalendarClickListener.onClick(calendar, position);
            }
        }
        if (startPosition >= 0) {
            List<Calendar> list = new ArrayList<>();
            for (int i = 0; i < 7; i++) {
                list.add(mItems.get(startPosition + i));
            }
            if (mDelegate.mWeekSelectListener != null) {
                mDelegate.mWeekSelectListener.onWeekSelect(list, isClick);
            }
            if (mDelegate.mWeekLongClickListener != null) {
                mDelegate.mWeekLongClickListener.onLongClick(list);
            }
        }
        return true;
    }

    @Override
    int setSelectedCalendar(Calendar calendar) {
        mCurrentItem = -1;
        if (calendar == null) return -1;
        int size = mItems.size();
        Calendar weekFirstDay = CalendarUtil.getWeekFirstDay(calendar, mDelegate.getWeekStart());
        for (int i = 0; i < size; i++) {
            Calendar cal = mItems.get(i);
            if (cal.equals(weekFirstDay) && i + 6 < size) {
                mCurrentItem = i;
                return i;
            }
        }
        return -1;
    }

    /**
     * 获取选中周的日期
     *
     * @return 选中周的日期
     */
    final List<Calendar> getSelectWeekCalendar() {
        if (mCurrentItem >= 0) {
            List<Calendar> list = new ArrayList<>();
            for (int i = 0; i < 7; i++) {
                list.add(mItems.get(mCurrentItem + i));
            }
            return list;
        }
        return null;
    }

    /**
     * 绘制选中的日期
     *
     * @param canvas       canvas
     * @param calendar     日历日历calendar
     * @param x            日历Card x起点坐标
     * @param y            日历Card y起点坐标
     * @param hasScheme    hasScheme 非标记的日期
     * @param weekPosition 选中周的位置【0-6】，其它为-1
     * @return 是否绘制onDrawScheme，true or false
     */
    protected abstract boolean onDrawSelected(@NonNull Canvas canvas, @NonNull Calendar calendar, int x, int y, boolean hasScheme, int weekPosition);

    /**
     * 绘制标记的日期,这里可以是背景色，标记色什么的
     *
     * @param canvas   canvas
     * @param calendar 日历calendar
     * @param x        日历Card x起点坐标
     * @param y        日历Card y起点坐标
     */
    protected abstract void onDrawScheme(@NonNull Canvas canvas, @NonNull Calendar calendar, int x, int y);

    /**
     * 绘制日历文本
     *
     * @param canvas       canvas
     * @param calendar     日历calendar
     * @param x            日历Card x起点坐标
     * @param y            日历Card y起点坐标
     * @param hasScheme    是否是标记的日期
     * @param isSelected   是否选中
     * @param weekPosition 选中周的位置【0-6】，其它为-1
     */
    protected abstract void onDrawText(@NonNull Canvas canvas, @NonNull Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected, int weekPosition);
}
